﻿using System;

using zijian666.Abstractions;
using zijian666.Convertor.Base;
using zijian666.Core;
using zijian666.ConvertExtensions;

using static System.Char;

namespace zijian666.Convertor;

/// <summary>
/// <seealso cref="char" /> 转换器
/// </summary>
public class CharConvertor : FromConvertor<char>, IFromConvertible<char>, IFrom<byte[], char>
{
    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, bool input) => input ? context.GetOption("TRUE_CHAR", 'Y') : context.GetOption("FALSE_CHAR", 'N');

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, char input) => input;

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, sbyte input) => input < MinValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, byte input) => (char)input;

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, short input) => input < MinValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
#pragma warning disable IDE0078 // 使用模式匹配
    public ConvertResult<char> From(IConvertContext context, ushort input) => input < MinValue || input > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);
#pragma warning restore IDE0078 // 使用模式匹配

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, int input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, uint input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, long input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, ulong input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, float input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, double input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, decimal input) => input is < MinValue or > MaxValue ? (ConvertResult<char>)context.ConvertFail(this, input) : new((char)input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, DateTime input) => context.ConvertFail(this, input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, string input) => input.Length == 1 ? new(input[0]) : (ConvertResult<char>)context.ConvertFail(this, input);

    /// <inheritdoc/>
    public ConvertResult<char> From(IConvertContext context, byte[] input)
    {
        if (input.Length > sizeof(char))
        {
            return context.ConvertFail(this, input);
        }
        Array.Resize(ref input, sizeof(char));
        return BitConverter.ToChar(input, 0);
    }
}
